#include "plotview.h"
#include "plotcontroller.h"
#include <QDebug>
#include "qwt_symbol.h"

PlotView::PlotView(PlotData *data, int w, int h) :
    m_width(w),
    m_height(h),
    plotdata(data),
	m_curveShowWid(NULL)
{
    this->Initialize();
    plotdata->registerObserver(this);
    plotcontroller = new PlotController(plotdata, this);
}

PlotView::~PlotView()
{
}

void PlotView::setWidth(int w)
{
    m_width = w;
    this->setMinimumSize(m_width, m_height);
}

void PlotView::setHeight(int h)
{
    m_height = h;
    this->setMinimumSize(m_width, m_height);
}

int PlotView::getHeight()
{
    return m_height;
}

int PlotView::getWidth()
{
    return m_width;
}

void PlotView::setCurveShowWidget(QWidget *w)
{
	m_curveShowWid = w;
}

QWidget *PlotView::getCurveShowWidget()
{
	return m_curveShowWid;
}

void PlotView::addLegend(const QString& )
{
	//QwtLegend *legend = new QwtLegend(this);
	//this->insertLegend(legend, QwtPlot::RightLegend);
}

void PlotView::setAxisXTitle(const QString& text)
{
	QwtText title(text);
	title.setFont(QFont("Ubuntu", 10));
	this->setAxisTitle(QwtPlot::xBottom, title);
}

void PlotView::setAxisYTitle(const QString& text)
{
	QwtText title(text);
	title.setFont(QFont("Ubuntu", 10));
	this->setAxisTitle(QwtPlot::yLeft, title);
}

PlotData *PlotView::getPlotData()
{
    return plotdata;
}

void PlotView::setPlotData(PlotData *data)
{
    plotdata = data;
}

int PlotView::getCurveCount()
{
	return plotdata->getCurveCount();
}

void PlotView::Initialize()
{
    m_curveCount = 0;
	m_currentBoldCurve = 0;
    this->setMinimumSize(m_width, m_height);
	m_zoomState = false;
	QwtPlotGrid *grid = new QwtPlotGrid();
	grid->attach(this);
}

void PlotView::update()
{
    double **xdata = plotdata->getXData();
    double **ydata = plotdata->getYData();
    int *pos = plotdata->getPos();

    for(int i = 0; i < m_curveCount; i ++){
        curves[i]->setSamples(xdata[i], ydata[i], pos[i]);
    }

    this->replot();
}

// get some color
Qt::GlobalColor PlotView::GetColorFromId(int curveId)
{
	Qt::GlobalColor color;
	switch(curveId){
		case 0:
			color = Qt::black;
			break;
		case 1:
			color = Qt::red;
			break;
		case 2:
			color = Qt::darkRed;
			break;
		case 3:
			color = Qt::green;
			break;
		case 4:
			color = Qt::darkGreen;
			break;
		case 5:
			color = Qt::blue;
			break;
		case 6:
			color = Qt::darkBlue;
			break;
		case 7:
			color = Qt::cyan;
			break;
		case 8:
			color = Qt::darkCyan;
			break;
		case 9:
			color = Qt::magenta;
			break;
		case 10:
			color = Qt::darkMagenta;
			break;
		case 11:
			color = Qt::darkGray;
			break;
		case 12:
			color = Qt::darkYellow;
			break;
		case 13:
			color = Qt::gray;
			break;
		case 14:
			color = Qt::yellow;
			break;
		case 15:
			color = Qt::lightGray;
			break;
		default:
			color = Qt::black;
			break;
	}
	return color;
}

// really add curve
void PlotView::addCurve(std::string cur_name)
{
	curves[m_curveCount] = new QwtPlotCurve(QString(cur_name.c_str()));
	curves[m_curveCount]->setRenderHint(QwtPlotItem::RenderAntialiased);
	curves[m_curveCount]->setPen(QPen(QColor(PlotView::GetColorFromId(m_curveCount))));
	curves[m_curveCount]->attach(this);
	m_curveCount ++;
}

void PlotView::showCurve(std::string cur_name)
{
    int curId = plotdata->getCurveId(cur_name);
    if(curId >= 0){
        this->showCurve(curId);
    }
}

void PlotView::hideCurve(std::string cur_name)
{
    int curId = plotdata->getCurveId(cur_name);
    if(curId >= 0){
        this->hideCurve(curId);
    }
}

void PlotView::boldCurve(std::string cur_name)
{
    int curId = plotdata->getCurveId(cur_name);
    if(curId >= 0){
        this->boldCurve(curId);
    }
}

void PlotView::unBoldCurve(std::string cur_name)
{
    int curId = plotdata->getCurveId(cur_name);
    if(curId >= 0){
        this->unBoldCurve(curId);
    }
}

void PlotView::showCurve(int cur_id)
{
    curves[cur_id]->attach(this);
    this->replot();
}

void PlotView::hideCurve(int cur_id)
{
    curves[cur_id]->detach();
    this->replot();
}

void PlotView::boldCurve(int cur_id)
{
	this->unBoldCurve(m_currentBoldCurve);
	QPen pen = curves[cur_id]->pen();
	pen.setWidth(2);
	curves[cur_id]->setPen(pen);
	m_currentBoldCurve = cur_id;
    this->replot();
}

void PlotView::unBoldCurve(int cur_id)
{
	QPen pen = curves[cur_id]->pen();
	pen.setWidth(0);
	curves[cur_id]->setPen(pen);
    this->replot();
}

void PlotView::mouseDoubleClickEvent(QMouseEvent *)
{
	m_zoomState = m_zoomState ? false:true;
	emit zoomStateChanged(m_zoomState);
}

// slots
void PlotView::AddData(double x, double y, int curve)
{
    plotcontroller->addData(x, y, curve);
}

void PlotView::AddData(double x[], double y[])
{
    plotcontroller->addData(x, y);
}

// response to user add action
void PlotView::AddCurve(std::string cur_name)
{
    plotcontroller->addCurve(cur_name);
}

void PlotView::SetCurveState(std::string cur_name, bool state)
{
    if(state == true)
        this->showCurve(cur_name);
    else this->hideCurve(cur_name);
}

void PlotView::BoldCurve(std::string cur_name)
{
	this->boldCurve(cur_name);
}
